package com.game.service.comm;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class AESUtils {

    public static void test(String[] args) {
        encrypt("{噢噢噢噢}");
    }


    public static String[] encrypt(String plainText) {
        String[] ss = new String[2];
        try {
            String KEY = createKey();//实时生成的密钥,一次性的
            long start = System.currentTimeMillis();
            SecretKey secretKey = init(KEY);
            // 初始化加密器
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            //  System.out.println( "加密耗时:"+(System.currentTimeMillis() - start) + "ms");

            byte[] encryptedData = cipher.doFinal(plainText.getBytes());
            String encoder = Base64.getEncoder().encodeToString(encryptedData);//加密数据
            String key = Base64.getEncoder().encodeToString(RSAUtils.encrypt(KEY));//加密密钥RSA-需要解密

            // System.out.printf("原始长度:%s,加密长度:%s,加密内容:%s\n ", plainText.getBytes().length, encoder.length(), encoder);
            // 打印加密后的数据（Base64 编码）
            byte[] encryptedData2 = Base64.getDecoder().decode(encoder);
            // System.out.println("转数组: " + Arrays.toString(encryptedData2));
            // 初始化解密器
            cipher.init(Cipher.DECRYPT_MODE, secretKey);

            // 解密数据
            byte[] decryptedData = cipher.doFinal(encryptedData2);
            String decryptedText = new String(decryptedData);

            // 打印解密后的数据
            // System.out.println("解密数据: " + decryptedText);
            ss[0] = encoder;
            ss[1] = key;

            return ss;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ss;
    }

    public static EncipheredData createEncipheredData(String plainText) {
        String[] arg = encrypt(plainText);
        EncipheredData encipheredData = new EncipheredData();
        encipheredData.setCipherContent(arg[0]);
        encipheredData.setCipherKey(arg[1]);
        return encipheredData;
    }

    public static String createKey() {
        // 生成密钥
        KeyGenerator keyGenerator = null;
        try {
            keyGenerator = KeyGenerator.getInstance("AES");
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        keyGenerator.init(128); // 设置密钥长度为128位
        SecretKey secretKey = keyGenerator.generateKey();
        // 将密钥转换为字节数组
        byte[] encodedKey = secretKey.getEncoded();
        // 使用Base64编码将字节数组转换为字符串
        String base64EncodedKey = Base64.getEncoder().encodeToString(encodedKey);
        // System.out.printf("ASE 密钥:%s\n ", base64EncodedKey);
        return base64EncodedKey;
    }

    public static SecretKeySpec init(String base64EncodedKey) {
        try {
            // 将Base64编码的字符串解码为字节数组
            byte[] decodedKey = Base64.getDecoder().decode(base64EncodedKey);

            // 使用字节数组创建SecretKeySpec对象
            SecretKeySpec secretKey = new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES");
            // 输出密钥信息（仅用于验证）
            // System.out.println("Restored SecretKey Algorithm: " + secretKey.getAlgorithm());
            // System.out.println("Restored SecretKey Format: " + secretKey.getFormat());
            return secretKey;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decrypt(String encoder, String AESKey) {
        String decryptedText = "";
        try {
            SecretKey secretKey = init(AESKey);
            // 初始化加密器
            Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
            //加密数据转字节
            byte[] encryptedData2 = Base64.getDecoder().decode(encoder);
            // 初始化解密器
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            // 解密数据
            byte[] decryptedData = cipher.doFinal(encryptedData2);
            decryptedText = new String(decryptedData);
            // 打印解密后的数据
            System.out.println("解密数据: " + decryptedText);
            return decryptedText;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return decryptedText;
    }
}